using System;
using OpenRay;
using System.Collections.Generic;

namespace Tests
{
	public class ObjReader
	{
		private List<OpenRay.Point[]> vertices = new List<OpenRay.Point[]>();
		private List<OpenRay.Vector[]> normals = new List<OpenRay.Vector[]>();
		
		public ObjReader (string filename)
		{		
			string[] lines = System.IO.File.ReadAllLines(filename);
			
			List<OpenRay.Point> p = new List<OpenRay.Point>();
			List<OpenRay.Vector> n = new List<OpenRay.Vector>();
			
			foreach( string line in lines )
			{
				if ( line.StartsWith("vn" ) ) {
					float x, y, z;
					char[] delimiter = new char[1] { ' ' };
					string[] split = line.Split(delimiter);
					float.TryParse(split[1], out x);
					float.TryParse(split[2], out y);
					float.TryParse(split[3], out z);
					
					n.Add( new OpenRay.Vector(x, y, z) );
				} else if ( line.StartsWith("v" ) ) {
					float x, y, z;
					char[] delimiter = new char[1] { ' ' };
					string[] split = line.Split(delimiter);
					float.TryParse(split[1], out x);
					float.TryParse(split[2], out y);
					float.TryParse(split[3], out z);
					
					p.Add( new OpenRay.Point(x, y, z, 1f) );
				} else if ( line.StartsWith("f") ) {
					int v1, v2, v3, n1, n2, n3;
					char[] delimiter = new char[2] { ' ', '/' };
					string[] split = line.Split(delimiter);
					int.TryParse(split[1], out v1);
					int.TryParse(split[3], out n1);
					int.TryParse(split[4], out v2);
					int.TryParse(split[6], out n2);
					int.TryParse(split[7], out v3);
					int.TryParse(split[9], out n3);
					
					vertices.Add(new OpenRay.Point[3] { p[v1 - 1], p[v2 - 1], p[v3 - 1] } );
					normals.Add(new OpenRay.Vector[1] { n[n1 - 1] } ); //, n[n2 - 1], n[n3 - 1] } );
				}
			}
		}
		
		public OpenRay.FrameBuffer Draw(Material[] m, IList<OpenRay.Light> lts)
		{
			IScene s = new OctTreeScene(new BoundingBox( new OpenRay.Point( -100, -100, -100 ), new OpenRay.Point( 100, 100, 100 ) ), 12, 100 );
			
			for( int i = 0; i < vertices.Count; i++ )
			{
				FlatTriangleGeometry geom = new FlatTriangleGeometry(vertices[i], normals[i], m);
				Primitive p = new Primitive( Matrix.CreateTranslate(0, 0, -5f),
				                             Matrix.CreateTranslate(0, 0, 5f),
				                             geom, lts );
				
				s.AddPrimitive(p);
			}
			
			Matrix c2w = Matrix.Inverse( Matrix.CreateFrustum(-1f, 1f, -1f, 1f, 1f, 50f) );
			OpenGLCamera camera = new OpenGLCamera(s, c2w, 500, 500 );
			
			return camera.Render();
		}
	}
}

